본문으로 건너뛰기

2.10~2.13Readme

객체속성과 적용되는 타입을 배우자

  • 객체 속성에도 옵셔널이나 readonly수식어가 가능하다.
interface Example {
hello: string;
world?: string;
readonly wow: boolean;
}

객채속성의 특이점

  • 객체를 타이핑할 때 선언하지 않은 속성에 대해서 에러가 발생한다
interface Example{
hello : string
}
const example : Example : {
hello : "hi"
why : "나만 에러야"
}


const example2 {
hello : "hi"
why : "나만 에러야"
}

// 에러 안남
const obj : Example = example2
  • 객체 리터럴을 대입했나 변수를 대입했나에 따라 타입 검사방식이달라진다.
  • 에러검사는 여러개의 에러가 나올 수 있다. 그렇기에 필요한 에러를 찾아나가면 된다.

객체 리터럴 대입시

  • 잉여 검사 속성을 실행한다.
  • 타입 선언에서 선언 치 않은 속성 사용시 에러를 표시함을 의미한다.

변수 대입시

  • 이때는 객체간 대입가능성을 본다.

인덱스 접근 타입

type Animanl {
name : string
}

type N1 = Animal['name']
type N2 = Animal.name // 불가능
  • 위 처럼 타입에 연동되게 할 수 있다. 이렇게 객체 속성의 타입에 접근하는 방식을 인덱스 접근 타입이라고 부른다.

  • keyof 를 이용해 키와 값의 타입을 알 수 있다.

const obj = {
hello: "world",
name: "zero",
age: 28,
};

type Keys = keyof typeof obj;
type Values = (typeof obj)[Keys];

매핑된 객체 타입

  • 시그니처에서 사용할 수 있는 타입은 string number symbol 이들과 유니온 뿐이다.
type OnlyBoolsAndHorses = {
[key: string]: boolean | Horse;
};

const conforms: OnlyBoolsAndHorses = {
del: true,
rodney: false,
};

// in을 이용해 못쓰는 속성도 가능
type Hello = {
[ket in 'hello | ''hi'] : string
}
  • 미리 선언되지 않은 속성의 유형을 선언할 수 있다.
  • 읽기전용으로 만들기 위해 ?readonly도 가능하다.
  • 항상 좁은타임을 넗은 타입에 대입해야한다

타입을 집합으로 생각하자

const num: string | number;
  • 위 요소는 합집합이다.
  • 교집합 연산을 위해선 &를 사용한다. 그러나 string 이면서number인 타입이 있을 수 있을까?
  • 이렇게 없는 집합을 공집합이라 칭한다 never가 이 역활을 맡는다.
  • 전체집합은 unknown이 맡는다.
  • 가장 넓은 집합은 unknown이고 좁은 집합은 never임을 알 수 있다.
type D = {} & (string | null); // 교집합은 string임을 알 수 있다.
type H = { a: "b" } & number; // {a : "b"} & number가 타입으로 잡힙
  • 위 예시에서 Hnever처리하지 않는다. 이를 브랜딩기법이라 칭한다.

타입도 상속이 가능하다.

class Animal {
constructor(name) {
this.name = name;
}
}

class Dog extends Aniaml {
bark() {
console.log("멍멍");
}
}

// 타입 상속 방식
type Animal = {
name: string;
};
type Dog = Animal & {
bark(): void;
};

interface cat extends Animal {
meow(): void;
}
  • &를 이용해 타입을 상속할 수 있다.
  • 타입별칭이 & 인터페이스 상속이 가능하다

객체간의 대입할 수 있는 지 확인법

interface A {
name: string;
}
interface B {
name: string;
age: number;
}

const aObj = {
name: "zero",
};
const bObj = {
name: "nero",
age: 32,
};
const aToA: A = aObj;
const bToA: A = bObj;
const aToB: B = aObj;
// Property 'age' is missing in type '{ name: string; }' but required in type 'B'.
const bTob: B = bObj;
  • 넓은 타입은 좁은타입에 넣지 못해 에러가 남을 알 수 있다.
  • 튜플또한 마찬가지로 배열보다 좁은 타입이기에 배열은 튜플에 대입할 수 없다.
  • 이를 해결하기 위해 옵셔널을 사용할 수 있다.

구조적 타이핑

interface Money {
amount: number;
unit: string;
}

interface Liter {
amount: number;
unit: string;
}

const liter: Liter = { amount: 1, unit: "liter" };
const circle: Money = liter;
  • 타입스크립트에서는 모든 속성이 동일하면 객체 타입의 이름이 다르더라도 동일한 타입으로 취급한다.